package com.ruoyi.file.pdfFileHandle.service;

import com.deepoove.poi.XWPFTemplate;
import com.ruoyi.file.pdfFileHandle.domain.DateInfoVO;
import com.ruoyi.file.pdfFileHandle.domain.PdfFileBinderKnowTable;
import com.ruoyi.file.pdfFileHandle.domain.Person;
import com.ruoyi.file.pdfFileHandle.domain.WordFileTemplateVariable;
import com.ruoyi.file.utils.StringRegexUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import technology.tabula.*;
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName PdfFileHandleService
 * @Author fanzf
 * @Description
 * @Date 2024/9/29 9:50
 */
@Service
public class PdfFileHandleService {
    private static final Logger logger = LoggerFactory.getLogger(PdfFileHandleService.class);
    /**
     * pdf文件路径
     */
    private static final String PDF_FILE_PATH = "D:\\BaiduNetdiskDownload\\招标文件.pdf";
    /**
     * word template 路径
     */
    private static final String WORD_TEMPLATE_FILE_PATH = "D:\\BaiduNetdiskDownload\\template.docx";
    /**
     * word文档输出路径
     */
    private static final String WORD_FILE_PATH = "D:\\BaiduNetdiskDownload\\output.docx";
    /**
     * 换行符
     */
    private static final String END_CHAR = "\r\n";
    /**
     * 空格，制表符，换行符
     */
    private static final String SPLIT_CHAR_REGEX = "[\\r\\n\\t ]+";
    /**
     * 正则表达式，字符匹配：中文|字母|数字
     */
    private static final String CHAR_REGEX = "[\\u4e00-\\u9fa5\\da-zA-Z]+";
    /**
     * 项目管理班子成员
     */
    private static final String PERSON_MANAGER_LIST = "项目经理|技术负责人|安全员";
    /**
     * 字符串分隔符
     */
    private static final String STRING_SPLIT_REGEX = "\\|";



    /**
     * 处理pdf文件
     */
    public void handlePdfFileDataInvoke() {
        WordFileTemplateVariable wordFileTemplateVariable = new WordFileTemplateVariable();
        //1.获取文档中表格数据
        Map<String, PdfFileBinderKnowTable> tableMap = readPdfFileTableData();
        //2.从表格数据中获取word模板变量
        getWordFileVariableDataFromTableMap(tableMap, wordFileTemplateVariable);
        //3.获取文档中文本数据，补充word模板变量
        readPdfFileContext(wordFileTemplateVariable);
        //4.构建word模板变量map
        Map<String, Object> wordFileVariableMap = buildWordVariableMap(wordFileTemplateVariable);
        //5.根据word模板生成word文档
        generateWordDocument(wordFileVariableMap, WORD_TEMPLATE_FILE_PATH, WORD_FILE_PATH);
    }


    /**
     * 读取pdf中表格数据
     * 此方法会丢失跨页的表格数据，可以设置SpreadsheetExtractionAlgorithm模式为complex，会影响性能，暂不处理跨页
     * 跨页的数据从解析文本的方式获取数据
     * @return
     */
    public Map<String, PdfFileBinderKnowTable> readPdfFileTableData() {
        File file = new File(PDF_FILE_PATH);
        Map<String, PdfFileBinderKnowTable> dataMap = new HashMap<>();
        try (PDDocument document = PDDocument.load(file)) {
            ObjectExtractor extractor = new ObjectExtractor(document);
            PageIterator pages = extractor.extract();
            SpreadsheetExtractionAlgorithm algorithm = new SpreadsheetExtractionAlgorithm();
            for (PageIterator it = pages; it.hasNext(); ) {
                Page page =  it.next();
                List<Table> tables = algorithm.extract(page);
                for (Table table : tables) {
                    List<List<RectangularTextContainer>> rows = table.getRows();
                    for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) {
                        List<RectangularTextContainer> cells = rows.get(rowIndex);
                        PdfFileBinderKnowTable pdfFileBinderKnowTable = new PdfFileBinderKnowTable();
                        for (int cellIndex = 0; cellIndex < cells.size(); cellIndex++) {
                            String cellText = cells.get(cellIndex).getText();
                            switch (cellIndex) {
                                case 0:
                                    pdfFileBinderKnowTable.setOrder(cellText);
                                    break;
                                case 1:
                                    pdfFileBinderKnowTable.setName(cellText);
                                    break;
                                case 2:
                                    pdfFileBinderKnowTable.setContent(cellText.replaceAll(SPLIT_CHAR_REGEX, ""));
                                    break;
                            }
                        }
                        dataMap.put(pdfFileBinderKnowTable.getName(), pdfFileBinderKnowTable);
                    }
                }
            }
//            dataMap.forEach((k,v) -> {
//                logger.info("k:{},v:{}",k,v.toString());
//            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataMap;
    }


    /**
     * 读取pdf文件中文本数据
     */
    public void readPdfFileContext(WordFileTemplateVariable wordFileTemplateVariable) {
        File file = new File(PDF_FILE_PATH);
        try (PDDocument document = PDDocument.load(file)) {
            PDFTextStripper stripper = new PDFTextStripper();
            //PDFLayoutTextStripper stripper = new PDFLayoutTextStripper();
            int totalPage = document.getNumberOfPages();
            boolean projectNameFlag = false;//项目名称整个文档只执行一次
            for (int i=1;i<totalPage;i++) {
                // 设置按页提取
                stripper.setStartPage(i);
                stripper.setEndPage(i);
                String text = stripper.getText(document);
                String[] pages = text.split(END_CHAR);
                String pageInfo = pages[pages.length - 1]; //最后一行--页码信息
                projectNameFlag = getProjectName(text, projectNameFlag, wordFileTemplateVariable);
                getProjectManagerGroup(text, wordFileTemplateVariable);
                getProjectManager(text, wordFileTemplateVariable, pageInfo);


            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 从pdf文件表格中获取word变量数据
     * @param tableMap
     * @param wordFileTemplateVariable
     */
    private void getWordFileVariableDataFromTableMap(Map<String, PdfFileBinderKnowTable> tableMap, WordFileTemplateVariable wordFileTemplateVariable) {
        PdfFileBinderKnowTable projectStopTimeInfo  = tableMap.get("投标截止时间");
        if (null != projectStopTimeInfo) {
            String content = projectStopTimeInfo.getContent();
            getProjectStopTime(content, wordFileTemplateVariable);
        }

        PdfFileBinderKnowTable planProjectDateInfo  = tableMap.get("计划工期");
        if (null != projectStopTimeInfo) {
            String content = planProjectDateInfo.getContent();
            getPlanProjectDate(content, wordFileTemplateVariable);
        }

    }


    /**
     * 获取计划工期
     * @param text
     * @param wordFileTemplateVariable
     */
    private void getPlanProjectDate(String text, WordFileTemplateVariable wordFileTemplateVariable) {
        if (!StringUtils.isEmpty(text)) {
            wordFileTemplateVariable.setPlanProjectDate(text.replaceAll(SPLIT_CHAR_REGEX, "") + END_CHAR);
        }
    }


    /**
     * 获取截止时间 年-月-日 时-分-秒
     * @param text
     * @param wordFileTemplateVariable
     */
    private void getProjectStopTime(String text, WordFileTemplateVariable wordFileTemplateVariable) {
        if (!StringUtils.isEmpty(text)) {
            wordFileTemplateVariable.setProjectStopTimeDetailInfo(text.replaceAll(SPLIT_CHAR_REGEX, "") + END_CHAR);
            String regex = "（";
            int end = StringRegexUtil.charLocationByRegex(regex, text);
            if (end > 0) {
                String result = text.substring(0, end);
                wordFileTemplateVariable.setProjectStopTimeInfo(result.replaceAll(SPLIT_CHAR_REGEX, "") + END_CHAR);
            } else {
                logger.error("根据括号位置截取字符串获取截止时间错误");
            }
            DateInfoVO dateInfoVO = StringRegexUtil.yearMonthDayTime(text);
            BeanUtils.copyProperties(dateInfoVO,wordFileTemplateVariable);
        }
    }


    /**
     * 获取项目经理
     * @param text
     * @param wordFileTemplateVariable
     * @param pageInfo
     */
    private void getProjectManager(String text, WordFileTemplateVariable wordFileTemplateVariable, String pageInfo) {
        if (text.contains("项目经理")) {
            wordFileTemplateVariable.setProjectManager(text.replaceAll(SPLIT_CHAR_REGEX, "") + END_CHAR + "页码：" + pageInfo + END_CHAR);
        }
    }


    /**
     * 按行解析项目名称数据
     * @param text
     * @param projectNameFlag
     * @param wordFileTemplateVariable
     */
    private boolean getProjectName(String text, boolean projectNameFlag, WordFileTemplateVariable wordFileTemplateVariable) {
        String[] pages = text.split(END_CHAR);
        for (String lineInfo : pages) {
            if (lineInfo.contains("项目名称") && !projectNameFlag) {
                wordFileTemplateVariable.setProjectName(lineInfo);
                projectNameFlag = true;
                break;
            }
        }
        return projectNameFlag;
    }

    /**
     * 获取项目管理班子信息
     * @param text
     * @param wordFileTemplateVariable
     */
    private void getProjectManagerGroup(String text, WordFileTemplateVariable wordFileTemplateVariable) {
        if (text.contains("项目管理班子：")) {
            int start = text.indexOf("项目管理班子：");
            String tempInfo = text.substring(start);
            String regex = "（(\\d+)）";
            int end = StringRegexUtil.charLocationByRegex(regex, tempInfo);
            String result = tempInfo.substring(0, end);
            wordFileTemplateVariable.setProjectManagerGroup(result.replaceAll(SPLIT_CHAR_REGEX, "") + END_CHAR);
        }
    }


    /**
     * 解析部分word模板变量数据
     * @param wordFileTemplateVariable
     */
    private void parseTemplateVariable(WordFileTemplateVariable wordFileTemplateVariable) {
        String projectManagerGroup = wordFileTemplateVariable.getProjectManagerGroup();
        if (StringUtils.isNotEmpty(projectManagerGroup)) {
            projectManagerGroup = projectManagerGroup.replaceAll(SPLIT_CHAR_REGEX, "");
            String[] split = PERSON_MANAGER_LIST.split(SPLIT_CHAR_REGEX);
            Map<String, String> map = new HashMap<>();
            for (String person : split) {
                String matchValue = StringRegexUtil.matcherString(person + CHAR_REGEX + "人", projectManagerGroup);
                map.put(person, matchValue);
            }

            setObjectValueFromMap(wordFileTemplateVariable, map);

        }
    }


    private void setObjectValueFromMap(WordFileTemplateVariable wordFileTemplateVariable, Map<String, String> map) {
        Class<? extends WordFileTemplateVariable> clazz = wordFileTemplateVariable.getClass();
        // 获取声明的所有字段，包括private字段
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Person.class)) {
                Person myAnnotation = field.getAnnotation(Person.class);
                field.setAccessible(true);
                String person = myAnnotation.name();
                try {
                    field.set(wordFileTemplateVariable, map.get(person));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }


        }
    }

    /**
     * 生成word文档
     * @param columnInfo
     * @param templatePath
     * @param outputPath
     * @throws Exception
     */
    public void generateWordDocument(Map<String, Object> columnInfo, String templatePath, String outputPath) {
        XWPFTemplate template = XWPFTemplate.compile(templatePath).render(columnInfo);
        try (FileOutputStream out = new FileOutputStream(outputPath)) {
            template.writeAndClose(out);
        } catch (Exception e) {
            logger.error("生成word文档异常");
            e.printStackTrace();
        }
    }


    /**
     * 将对象转换为map
     * @param wordFileTemplateVariable
     */
    private Map<String, Object> Object2Map(WordFileTemplateVariable wordFileTemplateVariable) {
        // 将对象属性放到Map中
        Class<? extends WordFileTemplateVariable> clazz = wordFileTemplateVariable.getClass();
        Map<String, Object> propertiesMap = new HashMap<>();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true); // 如果字段是私有的，需要设置访问权限
            try {
                propertiesMap.put(field.getName(), field.get(wordFileTemplateVariable));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        /*// 打印Map内容
        propertiesMap.forEach((key, value) -> logger.info(key + ": " + value));*/
        return propertiesMap;
    }

    /**
     * 构建word模板变量map
     * @param wordFileTemplateVariable
     * @return
     */
    private Map<String, Object> buildWordVariableMap(WordFileTemplateVariable wordFileTemplateVariable) {
        //构建前解析部分数据
        parseTemplateVariable(wordFileTemplateVariable);
        return Object2Map(wordFileTemplateVariable);
    }

    public static void main(String[] args) {
        PdfFileHandleService test = new PdfFileHandleService();
        test.handlePdfFileDataInvoke();
    }


}
